
import urllib2

import StringIO

from google.appengine.api.urlfetch_errors import *
from google.appengine.api import urlfetch
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

from django.utils import simplejson

import gdata.oauth
import gdata.gauth

import gdata.docs.data
import gdata.docs.client
import gdata.docs.service

import gdata.spreadsheets.client
import gdata.apps
import gdata.apps.service

from gdata.apps.service import AppsForYourDomainException
from gdata.apps import UserEntry

username='blabla@gmail.com'
password='blublu'

APPLICATION_ID='200718614416'
CONSUMER_KEY='200718614416.apps.googleusercontent.com'
CONSUMER_SECRET='dk0l+dglJDNOxXdn4rIBHFnk'

SCOPES=['https://www.google.com/calendar/feeds/',
        'http://www.google.com/calendar/feeds/',
        'https://spreadsheets.google.com/feeds/',
        'http://spreadsheets.google.com/feeds/',
        'http://www.google.com/a/feeds/',
        'https://www.google.com/a/feeds/',
        'http://apps-apis.google.com/a/feeds/',
        'https://apps-apis.google.com/a/feeds/']  

def TwoLeggedOAuth(client):
    requestor_id=users.get_current_user().email()
    client.auth_token = gdata.gauth.TwoLeggedOAuthHmacToken(
        CONSUMER_KEY, 
        CONSUMER_SECRET, 
        requestor_id
    )
    return client

def getMenu(user):
    if not user:
        ret =  [("<a href=\"%s\">Sign in</a><br/>" % users.create_login_url("/"))]
    else:
        domain=user.email().split('@')[1]
        ret =[
                ("<a href=\"%s?domain=%s\">%s</a>" % ('/admin',domain,'Users')),
                ("<a href=\"%s?domain=%s\">%s</a>" % ('/sheets',domain,'Worksheets')),
                ("<a href=\"%s?domain=%s\">%s</a>" % ('/reports',domain,'Reports')),
                ("<a href=\"%s\">Sign out</a>" % (users.create_logout_url("/")))
        ]
    menu = ' | '.join(ret)
    return menu

def getXpenserFeed(url):
    try:
        password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
        top_level_url = "http://xpenser.com/api/v1.0"
        password_mgr.add_password(None, top_level_url, username, password)
        handler = urllib2.HTTPBasicAuthHandler(password_mgr)
        opener = urllib2.build_opener(handler)
        urllib2.install_opener(opener)
        request = urllib2.urlopen(url)
        feed = simplejson.load(request) 
    except IOError, e:
        feed = None
    return feed

def getHeader():
    user = users.get_current_user()
    if not user:
        ret = [getMenu(None)]
    else:            
        ret=[ 
             ("<h1>%s</h1>" % (user.email())),
             ("<h4>%s</h4>" % (getMenu(user))),
             ("%s=%s<br/>" % ('nickname',user.nickname())),
             ("%s=%s<br/>" % ('email',user.email())),
             ("%s=%s<br/>" % ('auth_domain',user.auth_domain())),
             ("%s=%s<br/>" % ('user_id',user.user_id())),
             ("%s=%s<br/>" % ('federated_provider',user.federated_provider())),
             ("%s=%s<br/>" % ('auth_domain',user.auth_domain())),
        ]
    return ret

class RequestHandler(webapp.RequestHandler):
    
    def footer(self):
        ret=['<h3>Query Parameters</h3>']
        if len(self.request.params):
            for k in self.request.params:
                ret.append("%s = %s</br>" % ( k, self.request.get(k) ) )
        return ''.join(ret)
    
    def get(self):                
        header = getHeader()
        if (header.__class__.__name__=='list'):
            options = self.getOptions()
            header.extend(options)
            html = ("".join(header))
        else:
            html = header
        self.response.out.write("<html><body>%s<br/>%s</body></html>" % (html,self.footer()) )
    
    def getOptions(self):
        return []
    


class Admin(RequestHandler):
    
    def getOptions(self):
        domain=users.get_current_user().email().split('@')[1]       
        client = gdata.apps.service.AppsService(domain=domain)       
        client.SetOAuthInputParameters(
           signature_method=gdata.auth.OAuthSignatureMethod.HMAC_SHA1, 
           consumer_key=CONSUMER_KEY, 
           consumer_secret=CONSUMER_SECRET, 
           two_legged_oauth=True
        )
        
        ret = ['<h2>User List</h2>']
        try:
            feed = client.RetrievePageOfUsers(                
                num_retries=3,
                delay=2
            )
            ret.append('<ul>')
            for usr in feed.entry:
                ret.append('<li>%s</li>' % (usr.title.text,))
            ret.append('</ul>')    
        except gdata.service.RanOutOfTries:
            ret.append('Request ran out of tries...')
        return ret
        

class Sheets(RequestHandler):
   
    def getOptions(self):
        client = gdata.spreadsheets.client.SpreadsheetsClient(source='AppsTes')
        client = TwoLeggedOAuth(client)
        ret = ['<h2>Spreadsheets</h2>']
        try:
            domain=users.get_current_user().email().split('@')[1]
            feed = client.GetSpreadsheets()
            ret.append('<ul>')
            for entry in feed.entry:
                link=entry.GetAlternateLink().href.replace('ccc',('a/%s/ccc'%(domain)))
                ret.append('<li><a href=\"%s\" target=\"_blank\" >%s</a></li>' % (link,entry.title.text))
            ret.append('</ul>')    
        except :
            ret.append('Request ran out of tries...')
        return ret   

class Reports(RequestHandler):
    def upload(self,name,content):
        client = gdata.docs.client.DocsClient(source='AppsTes')
        client = TwoLeggedOAuth(client)
        fileHandle = StringIO.StringIO(content)
        ms = gdata.data.MediaSource(
            file_handle=fileHandle,
            content_type=gdata.docs.service.SUPPORTED_FILETYPES['CSV'], 
            content_length=fileHandle.tell()
        )
        try:
            spreadsheet = client.Upload(
                media=ms, 
                title=name
            )
            fileHandle.close()
            return spreadsheet 
        except DownloadError,e:
            pass
        fileHandle.close()
        return None
    
    def buildToCSV(self,report_id):
        expenses=getXpenserFeed("http://xpenser.com/api/v1.0/expenses/?report=%s" % (report_id) )
        content=[]
        if len(expenses)>0:
            content.append(','.join(expenses[0].keys()))
            for item in expenses:                        
                values=[]
                for vlr in item.values():
                    if vlr:
                        if type(vlr).__name__=='list':
                            innerVlrs=[]
                            for innerItem in vlr:
                                if type(innerItem).__name__=='dict':
                                    strlist=[]
                                    for k,v in innerItem.iteritems():
                                        if not k=='id':
                                            strlist.append(str(v))
                                    innerVlrs.append(' | '.join(strlist))
                                else:
                                    innerVlrs.append('too deep')
                            values.append(' / '.join(innerVlrs))
                        else:
                            values.append(str(vlr))
                    else:
                        values.append('')
                content.append(','.join(values))
        return content
        
        
    def getOptions(self):
        report_id = self.request.get('id')
        report_name = self.request.get('name')
        if not report_id:
            ret = ['<h2>Reports:</h2>']
            reports = getXpenserFeed("http://xpenser.com/api/v1.0/reports/")        
            ret.append('<ul>')
            for item in reports:
                ref  = "%s&id=%d&name=%s" % (self.request.uri,item['id'],urllib2.quote(item['name']))
                link = '<a href="%s">Export to Google Spreadsheet</a>' % (ref)
                ret.append('<li><b>%s</b><br>Total %s<br>%s<br/><br/></li>' % (item['name'],item['total'],link) )
            ret.append('</ul>')
        else:
            confirm = self.request.get('confirm','no')
            if confirm=='yes':
                content = self.buildToCSV(report_id)
                #spreadsheet = None
                spreadsheet = self.upload('xpn_'+report_name, '\r\n'.join(content)) 
                if spreadsheet:
                    link = spreadsheet.GetAlternateLink().href
                    ret = [
                        '<h2>%s Exported</h2>' % (report_name),
                        '<a href=\"%s\" target=\"_blank\" >See online</a>' % (link)
                    ]
                else:
                    domain=users.get_current_user().email().split('@')[1]
                    ret = ['<h2>Exportation timeout</h2>',
                           'Before submit it again, take a look at <a href=\"sheets?domain=%s\">Worksheets page</a>' % domain ]
            else:    
                ret = ['<h2>Are you sure?</h2>',
                       '[<a href="%s&confirm=yes">Yes</a> | ' % (self.request.uri),
                       '<a href="%s">No</a>]' % (self.request.referer)]
        return ret

application = webapp.WSGIApplication([
    (r'/admin.*', Admin),
    (r'/sheets.*', Sheets),
    (r'/reports.*', Reports),
    (r'/.*', RequestHandler)
],debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
